package com.weipai.demo.util;


import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.*;


/**
 * 微信支付 工具类
 */
public class WxPayMessage {



    //开发平台id
    private static final String appId = PropUtils.getString("appId");
    //公众号id
    private static final String appIdApp = PropUtils.getString("appIdApp");
    //商户号
    private static final String mchId = PropUtils.getString("mchId");
    //商户API秘钥
    private static final String key = PropUtils.getString("key");
    //公众号秘钥
    private static final String SECRET = PropUtils.getString("SECRET");

    private String nonceStr = nonceStr();//随机字符串

    private String body;//商品描述

    private String outTradeNo = outTradeNo();//商户订单号

    private Integer totalFee;//总金额

    private String spbillCreateIp;//用户端IP

    private String notifyUrl;//通知地址（支付完成或失败后返回地址）

    private String tradeType = "APP";//支付类型 不用更改

    private String sign;//签名

    private String feeType = "CNY";//货币类型

    private String signType = "MD5";//签名类型

    private String detail;//商品详情

    private String timeExpire;//交易结束时间

    private String timeStart;//交易开始时间


    public String getTimeExpire() {
        return timeExpire;
    }

    public void setTimeExpire(String timeExpire) {
        this.timeExpire = timeExpire;
    }

    public String getTimeStart() {
        return timeStart;
    }

    public void setTimeStart(String timeStart) {
        this.timeStart = timeStart;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public String getSignType() {
        return signType;
    }

    public void setSignType(String signType) {
        this.signType = signType;
    }

    public String getFeeType() {
        return feeType;
    }

    public void setFeeType(String feeType) {
        this.feeType = feeType;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public static String getKey() {
        return key;
    }

    // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
    public final static String getIpAddress(HttpServletRequest request) throws IOException {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    //组合签名
    public String Sign(WxPayMessage wpm) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        SortedMap<String, Object> map = new TreeMap<String, Object>();
        map.put("appid", wpm.getAppIdApp());
        map.put("body", wpm.getBody());
        map.put("mch_id", wpm.getMchId());
        map.put("nonce_str", wpm.getNonceStr());
        map.put("notify_url", wpm.getNotifyUrl());
        map.put("out_trade_no", wpm.getOutTradeNo());
        map.put("spbill_create_ip", wpm.getSpbillCreateIp());
        map.put("total_fee", wpm.getTotalFee());
        map.put("trade_type", wpm.getTradeType());
        map.put("fee_type", wpm.getFeeType());
        map.put("sign_type", wpm.getSignType());
        map.put("detail", wpm.getDetail());
        Collection<String> keyset = map.keySet();
        List list = new ArrayList<String>(keyset);
        Collections.sort(list);
        SortedMap<Object, Object> map2 = new TreeMap<Object, Object>();
        for (int i = 0; i < list.size(); i++) {
            map2.put(list.get(i), map.get(list.get(i)));
        }

        StringBuffer sb = new StringBuffer();
        Set es = map2.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
//        sign = sb.toString()+"key=u89wgxc9j89tfbnm02l0543329cjkhga";
//        sign = sb.toString() + "key=gonglaodagonglaodagonglaoda88999";
        sign = sb.toString() + "key=04EF1BC6C6B5D0A5761463F970F4C378";
        MD5Util md51 = new MD5Util();
        String md5 = md51.MD5Encode(sign, "UTF-8");
        return md5;

    }

    //生成随机字符串
    public String nonceStr() {
        return UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
    }

    //生成订单号
    public String outTradeNo() {
        Random random = new Random();
        return System.currentTimeMillis() + String.valueOf(random.nextInt(2000000000));

    }

    public String getAppId() {
        return appId;
    }

    public String getSecret() {
        return SECRET;
    }

    public String getMchId() {
        return mchId;
    }

    public String getNonceStr() {
        return nonceStr;
    }

    public void setNonceStr(String nonceStr) {
        this.nonceStr = nonceStr;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getOutTradeNo() {
        return outTradeNo;
    }

    public void setOutTradeNo(String outTradeNo) {
        this.outTradeNo = outTradeNo;
    }

    public Integer getTotalFee() {
        return totalFee;
    }

    public void setTotalFee(Integer totalFee) {
        this.totalFee = totalFee;
    }

    public String getSpbillCreateIp() {
        return spbillCreateIp;
    }

    public void setSpbillCreateIp(String spbillCreateIp) {
        this.spbillCreateIp = spbillCreateIp;
    }

    public String getNotifyUrl() {
        return notifyUrl;
    }

    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }

    public String getTradeType() {
        return tradeType;
    }

    public void setTradeType(String tradeType) {
        this.tradeType = tradeType;
    }

    public  String getAppIdApp() {
        return appIdApp;
    }
}
